package com.eptok.weixin.util;

import java.io.InputStream;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

import yspay.express.bean.CheckBean;
import yspay.express.bean.message.EncryptMessage;
import yspay.express.bean.responsemessage.ResponseArticle;
import yspay.express.bean.responsemessage.ResponseImageMessage;
import yspay.express.bean.responsemessage.ResponseNewsMessage;
import yspay.express.bean.responsemessage.ResponseServerMessage;
import yspay.express.bean.responsemessage.ResponseTempleteMessage;
import yspay.express.bean.responsemessage.ResponseTextMessage;

public class MessageUtil {

	/** 
	 * 请求消息类型：文本 
	 */  
	public static final String REQ_MESSAGE_TYPE_TEXT = "text";  

	/** 
	 * 请求消息类型：图片 
	 */  
	public static final String REQ_MESSAGE_TYPE_IMAGE = "image";  

	/** 
	 * 请求消息类型：链接 
	 */  
	public static final String REQ_MESSAGE_TYPE_LINK = "link";  

	/** 
	 * 请求消息类型：地理位置 
	 */  
	public static final String REQ_MESSAGE_TYPE_LOCATION = "location";  

	/** 
	 * 请求消息类型：客服
	 */  
	public static final String REQ_MESSAGE_TYPE_SERVER = "transfer_customer_service";  

	/** 
	 * 请求消息类型：音频 
	 */  
	public static final String REQ_MESSAGE_TYPE_VOICE = "voice";  
	
	/** 
	 * 请求消息类型：推送事件      
	 */  
	public static final String REQ_MESSAGE_TYPE_EVENT = "event";  

	/** 
	 * 事件类型：subscribe(订阅) 
	 */  
	public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";  

	/** 
	 * 事件类型：unsubscribe(取消订阅) 
	 */  
	public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";  

	/** 
	 * 事件类型：CLICK(自定义菜单点击事件) 
	 */  
	public static final String EVENT_TYPE_CLICK = "CLICK";  
	
	/**
	 * scan(关注用户扫描带参数二维码)
	 */
	public static final String EVENT_TYPE_SCAN = "scan";
	
	
	/** 
	 * 返回消息类型：文本 
	 */  
	public static final String RESP_MESSAGE_TYPE_TEXT = "text";  
	/** 
	 * 返回消息类型：图片 
	 */  
	public static final String RESP_MESSAGE_TYPE_IMAGE = "image";  
	/** 
	 * 返回消息类型：音乐 
	 */  
	public static final String RESP_MESSAGE_TYPE_MUSIC = "music";  

	/** 
	 * 返回消息类型：图文 
	 */  
	public static final String RESP_MESSAGE_TYPE_NEWS = "news";  
	
	/**
	 * 解析微信发过来的xml消息,同时解密
	 * @param request
	 * @return
	 */
	public static Map<String,String> parseXml(HttpServletRequest request,CheckBean bean) throws Exception {
			
		Map<String,String> map = new HashMap<String, String>();
		
		//从request中获取输入流
		InputStream inputStream = request.getInputStream();
		//dom4j读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		//获取根
		Element root = document.getRootElement();
		//获取子
		List<Element> elementList = root.elements();
		
		//遍历所有子节点
		for (Element e : elementList) {
			map.put(e.getName(), e.getText());
		}
		
		return map;
		/*EncryptMessage enc = new EncryptMessage();
		enc.setToUserName(map.get("ToUserName"));
		enc.setEncrypt(map.get("Encrypt"));
		
		xstream.alias("xml", enc.getClass());
		String encryptMsg  = xstream.toXML(enc);
		
		LogUtil.APP.info("收到的密文如下:\n"+encryptMsg);

//		String msgSignature = request.getParameter("msg_signature");
//		String timeStamp = request.getParameter("timestamp");
//		String nonce = request.getParameter("nonce");
		String msgSignature = bean.getMsg_signature();
		String timeStamp = Long.toString(bean.getTimestamp());
		String nonce = Long.toString(bean.getNonce());
		
		LogUtil.APP.info("msgSignature:"+msgSignature+"--timeStamp:"+timeStamp+"--nonce:"+nonce);
		
		WXBizMsgCrypt wc = new WXBizMsgCrypt(GeneralConstant.TOKEN, GeneralConstant.ENCODING_AES_KEY, GeneralConstant.APPID);
		
		String decryptMsg = wc.decryptMsg(msgSignature, timeStamp, nonce, encryptMsg);
		
		LogUtil.APP.info("解密后的密文如下:\n"+decryptMsg);
		
		Map<String,String> msgMap = new HashMap<String, String>();
		//解析解密后的xml
		Document doc = DocumentHelper.parseText(decryptMsg); // 将字符串转为XML
		Element rootele = doc.getRootElement(); // 获取根节点
		List<Element> childList = rootele.elements();
		for (Element e : childList) {
			msgMap.put(e.getName(), e.getText());
		}
		
		//释放资源
		inputStream.close();
		inputStream = null;
		
		return msgMap;*/
		
	}
	
	/**
	 * 解析微信发过来的xml消息成xml,不解密
	 * @param request
	 * @return
	 */
	public static String parseToXml(HttpServletRequest request) throws Exception {
		
		Map<String,String> map = new HashMap<String, String>();
		
		//从request中获取输入流
		InputStream inputStream = request.getInputStream();
		//dom4j读取输入流
		SAXReader reader = new SAXReader();
		Document document = reader.read(inputStream);
		//获取根
		Element root = document.getRootElement();
		//获取子
		List<Element> elementList = root.elements();
		
		//遍历所有子节点
		for (Element e : elementList) {
			map.put(e.getName(), e.getText());
		}
		
		EncryptMessage enc = new EncryptMessage();
		enc.setToUserName(map.get("ToUserName"));
		enc.setEncrypt(map.get("Encrypt"));
		
		xstream.alias("xml", enc.getClass());
		String encryptMsg  = xstream.toXML(enc);
		
		LogUtil.APP.info("收到的密文如下:\n"+encryptMsg);
		
		return encryptMsg;
		
	}
	
	/**
	 * 扩展XStream使其支持CDATD
	 */
	private static XStream xstream = new XStream( new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				
				public void startNode(String name,Class clazz) {
					super.startNode(name, clazz);
				}
				
				protected void writeText(QuickWriter writer,String text) {
					//对所有xml节点转换都增加CDATA标记
					boolean cdata = true;
					if(cdata) {
						writer.write("<![CDATA[");
						writer.write(text);
						writer.write("]]>");
					}else {
						writer.write(text);
					}
				}
			};
		}
	});
	
	/**
	 * 文本消息转xml
	 * @param text
	 * @return
	 */
	public static String textMsgToXml(ResponseTextMessage text) {
		xstream.alias("xml", text.getClass());
		return xstream.toXML(text);
	}
	
	/**
	 * 图片消息转xml
	 * @param image
	 * @return
	 */
	public static String imageMsgToXml(ResponseImageMessage image) {
		xstream.alias("xml", image.getClass());
		return xstream.toXML(image);
	}
	
	/**
	 * 图文消息转xml
	 * @param news
	 * @return
	 */
	public static String newsMsgToXml(ResponseNewsMessage news) {
		ResponseArticle c=new ResponseArticle();
		xstream.alias("xml", news.getClass());
		xstream.alias("item", c.getClass());
		return xstream.toXML(news);
	}


	/**
	 * 客服消息转xml
	 * @param image
	 * @return
	 */
	public static String serverMsgToXml(ResponseServerMessage server) {
		xstream.alias("xml", server.getClass());
		return xstream.toXML(server);
	}

	/**
	 * 模板消息转xml
	 * @param image
	 * @return
	 */
	public static String templeteMsgToXml(ResponseTempleteMessage msg) {
		xstream.alias("xml", msg.getClass());
		return xstream.toXML(msg);
	}

}
